package com.atguigu.spring.aop.annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.sql.Blob;
import java.util.Arrays;

/**
 * @author wk
 * @create 2021-06-03 23:48
 */
@Component
// 其标识为一个切面组件
@Aspect
public class CalculateProxy  {

    @Pointcut("execution(* com.atguigu.spring.aop.annotation.*.*(..))")
    public void pointCut(){
    }

    @Before("pointCut()")
    public void beforeMethod(JoinPoint joinPoint){
        // JoinPoint表示当前通知作用于的连接点，可以通过此对象获取连接点相关信息，例如方法名、参数
        System.out.println("Logger--> 前置通知，方法名"+joinPoint.getSignature().getName()+",参数"+ Arrays.toString(joinPoint.getArgs()));
    }
    @After("pointCut()")
    public void afterMethod(JoinPoint joinPoint){
        // JoinPoint表示当前通知作用于的连接点，可以通过此对象获取连接点相关信息，例如方法名、参数
        System.out.println("Logger--> 后置通知，方法名"+joinPoint.getSignature().getName()+",参数"+ Arrays.toString(joinPoint.getArgs()));
    }
    @AfterReturning(value = "pointCut()",returning = "result")
    public void returningMethod(JoinPoint joinPoint,Object result){
        // JoinPoint表示当前通知作用于的连接点，可以通过此对象获取连接点相关信息，例如方法名、参数
        System.out.println("Logger--> 返回通知，方法名"+joinPoint.getSignature().getName()+",参数"+ Arrays.toString(joinPoint.getArgs())+"返回值"+result);
    }
    @AfterThrowing(value = "pointCut()",throwing = "ex")
    public void throwingMethod(JoinPoint joinPoint,Throwable ex){
        // JoinPoint表示当前通知作用于的连接点，可以通过此对象获取连接点相关信息，例如方法名、参数
        System.out.println("Logger--> 异常通知，方法名"+joinPoint.getSignature().getName()+",参数"+ Arrays.toString(joinPoint.getArgs())+"异常"+ex);
    }

    @Around("pointCut()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        Object object = null;
        try {
            System.out.println("Logger-->环绕前置通知");
            //进行中的连接点所对应的目标对象的方法的执行
            object = joinPoint.proceed();
            System.out.println("Logger-->环绕返回通知");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("Logger-->环绕异常通知");
        }finally {
            System.out.println("Logger-->环绕后置通知");
        }
        return object;
    }
}
